package com.uye.framework.command;

import java.util.HashMap;
import java.util.Map;

import com.uye.framework.dto.IDTO;
import com.uye.framework.exception.CommandConfigurationException;
import com.uye.framework.exception.CommandNotFoundException;

/**
 * 
 * @author uye
 */
public class CommandFactory<C extends IStatefulCommand, M extends IDTO> {

	@SuppressWarnings("rawtypes")
	private Map<String, CommandFactoryEntry<C,M>> registeredCommands = new HashMap<String, CommandFactoryEntry<C,M>>();

	protected CommandFactoryEntry getCommandEntry(String commandName)
			throws CommandNotFoundException {
		verifyCommandRegistration(commandName);
		return registeredCommands.get(commandName);
	}

	public Class<C> getCommand(String commandName)
			throws CommandNotFoundException {
		verifyCommandRegistration(commandName);
		return registeredCommands.get(commandName).getCommandClass();
	}

	public Class<M> getModel(String commandName)
			throws CommandNotFoundException {
		verifyCommandRegistration(commandName);
		return registeredCommands.get(commandName).getModelClass();
	}

	private void verifyCommandRegistration(String commandName)
			throws CommandNotFoundException, CommandConfigurationException {
		if (!isCommandRegistered(commandName)
				|| null == registeredCommands.get(commandName)) {
			throw new CommandNotFoundException("Command " + commandName
					+ " has not been assigned.");
		}
		if (null == registeredCommands.get(commandName)
				.getCommandClass()) {
			throw new CommandConfigurationException("Command " + commandName
					+ " has no designated Command class.");
		}
		if (null == registeredCommands.get(commandName)
				.getModelClass()) {
			throw new CommandConfigurationException("Command " + commandName
					+ " has no designated Model class.");
		}
	}
	
	

	public void setRegisteredCommands(
			Map<String, CommandFactoryEntry<C,M>> registeredCommands) {
		this.registeredCommands = registeredCommands;
	}

	public Map<String, CommandFactoryEntry<C,M>> getRegisteredCommands() {
		return registeredCommands;
	}

	public boolean isCommandRegistered(String commandName) {
		return registeredCommands.containsKey(commandName);
	}
}
